/*
 * NInputGate.java
 * 
 * last update: 16.01.2010 by Stefan Saru
 * 
 * author:	Alec(panovici@elcom.pub.ro)
 * 
 * Obs:
 */

package engine;

import java.util.*;
import java.io.*;
import middle.*;

/**
 * guess..
 */

class NInputGate extends StdGate implements Monitor, Executable{

	BitVector lastInput, lastOutput;
	Expression inputs;
	LeftValue output;

	NInputGate(NameSpace parent, Delay3 delay, 
			ModuleInstanceDescription id, byte type) throws ParseException
			{
		this(parent, delay, null, null, id, type);
			}

	NInputGate(NameSpace parent, Delay3 delay,
			LeftValue output, Expression inputs,
			ModuleInstanceDescription id, byte type) throws ParseException
			{
		super(parent, delay, type, id);
		this.output = output;
		this.inputs = inputs;
		inputs.addMonitor(this);
		try {
			lastInput = inputs.evaluate().getBits();
		} catch (InterpretTimeException itex) {
			throw new ParseException (itex.toString());
		}

		lastOutput = BitVector.bZ();
			}

	public void trigger()throws InterpretTimeException {

		BitVector curInput = inputs.evaluate().getBits();
		xConsole.debug("NInputGate: trigger: lastVal: " + lastInput +
				" curinput: " + curInput);
		if (curInput.equals(lastInput)) return;
		lastInput = curInput;
		BitVector curOutput = (BitVector) curInput.duplicate();
		curOutput.genericReduction(truthTables[type]);
		if (curOutput.equals(lastOutput)) return;
		int iDelay = Wire.computeTransitionDelayFor(lastOutput, curOutput, delay);
		lastOutput = curOutput;
		lastUpdateTime = Time.oClock() + iDelay;
		Time.addFinisher(iDelay, new GenericInstruction(this));
	}

	public void execute ()throws InterpretTimeException {
		if (lastUpdateTime < Time.oClock()) return; //not now
		xConsole.trace(this + ": " + output + " <<< " + lastOutput);
		output.assign(lastOutput);
	}

}



